<template>
  <div>
    <div>
      计时：{{ date.days }}天{{ date.hours }}时{{ date.minutes }}分{{
        date.seconds
      }}秒{{ date.milliseconds }}毫秒
    </div>
    <div class="btnGroup">
      <g-button @click.native="handStart">启动</g-button>
      <g-button @click.native="handPause" type="primary">暂停</g-button>
      <g-button @click.native="handContinue">继续</g-button>
      <g-button @click.native="handReset" type="success">重置</g-button>
    </div>
  </div>
</template>

<script>
// 基于requestAnimationFrame实现一个倒计时组件
// 1.解析时间
// 2.补上暂停的时间
export default {
  // eslint-disable-next-line vue/multi-word-component-names
  name: 'g-timer',
  data() {
    return {
      date: {
        days: 0,
        hours: 0,
        minutes: 0,
        seconds: 0,
        milliseconds: 0,
      },
      dateCopy: {},
      rafId: null,
      stopTime: 0,
      startTime: 0,
      // 是否正在计时中
      isTiming: false,
    }
  },
  created() {
    this.dateCopy = this.deepClone(this.date)
  },
  methods: {
    process(time) {
      time = time - this.startTime
      const vm = this
      const resTime = vm.parseTime(time)
      Object.assign(vm.date, resTime)
      this.rafId = window.requestAnimationFrame(this.process)
    },
    /**
     * 解析时间
     * @param {*} time
     * @return {*}
     */
    parseTime(time) {
      let SECOND = 1000
      let MINUTE = SECOND * 60
      let HOUR = MINUTE * 60
      let DAY = HOUR * 24
      const milliseconds = Math.floor(time % SECOND)
      const seconds = Math.floor((time % MINUTE) / SECOND)
      const minutes = Math.floor((time % HOUR) / MINUTE)
      const hours = Math.floor((time % DAY) / HOUR)
      const days = Math.floor(time / DAY)
      return {
        total: time,
        days,
        hours,
        minutes,
        seconds,
        milliseconds,
      }
    },
    /**
     * 启动定时器
     */
    handStart() {
      if (this.isTiming) {
        return
      }
      this.startTime = performance.now()
      this.isTiming = true
      this.rafId = window.requestAnimationFrame(this.process)
    },
    /**
     * 暂停
     */
    handPause() {
      if (!this.isTiming) {
        return
      }
      this.isTiming = false
      this.stopTime = performance.now()
      if (this.rafId) {
        window.cancelAnimationFrame(this.rafId)
      }
    },
    /**
     * 继续
     */
    handContinue() {
      if (this.isTiming) {
        return
      }
      this.isTiming = true
      // 开始时间改变，等于原有的开始时间加上当前时间减去暂停时候的时间
      this.startTime += performance.now() - this.stopTime
      this.rafId = window.requestAnimationFrame(this.process)
    },
    /**
     * 重置
     */
    handReset() {
      this.handPause()
      this.date = this.deepClone(this.dateCopy)
    },
  },
}
</script>

<style lang="scss" scoped>
.btnGroup {
  margin-top: 10px;
  button {
    margin-right: 10px;
  }
}
</style>
